package com.miplus.ccrm.uploadjob.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.CmdResVo;
import com.miplus.ccrm.common.EnumRCode;
import com.miplus.ccrm.common.JPubUtils;
import com.miplus.ccrm.common.ServiceException;
import com.miplus.ccrm.uploadjob.controller.vo.UpRecResVo;
import com.miplus.ccrm.uploadjob.pojo.TRecorder;
import com.miplus.ccrm.uploadjob.mapper.TRecorderMapper;
import lombok.extern.slf4j.Slf4j;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;

/**
 * @author pc
 * @description 针对表【t_recorder】的数据库操作Service实现
 * @createDate 2024-07-31 16:12:41
 */
@Service
@Slf4j
public class TRecorderServiceImpl extends ServiceImpl<TRecorderMapper, TRecorder>
        implements TRecorderService {

    @Value("${cti.recordfileDir:}")
    private String cti_recfileDir;

    @Value("${cti.robotRecordfileDir:}")
    private String cti_robotRecfileDir;

    @Value("${cti.recorderid}")
    private String cti_recorderid;

    @Value("${cti.recorderip}")
    private String cti_recorderip;

    @Value("${ccrm.upload.filedir:}")
    private String upload_filedir;

    @Value("${ccrm.upload.ipaddr:}")
    private String upload_ipaddr;

    @Override
    public void OnPlayRecord(String callid, String agentid, HttpServletResponse response) {
        log.info("OnPlayRecord:callid={},agentid={},recorderid={},recorderip={}", callid, agentid, cti_recorderid, cti_recorderip);

        List<TRecorder> tRecorderList = baseMapper.selectList(new MPJLambdaWrapper<TRecorder>()
                .selectAll(TRecorder.class)
                //.eq("callid", callid)
                .eq(TRecorder::getRecorderid, callid)
                //.and(i -> i.eq("callid", callid).or().eq("recorderid",callid))
                .eq(JPubUtils.IsNotEmpty(cti_recorderid), "recorderid", cti_recorderid)
                .eq(JPubUtils.IsNotEmpty(cti_recorderip), "recorderip", cti_recorderip)
                .eq(JPubUtils.IsNotEmpty(agentid), "agentid", agentid)
        );

        if (JPubUtils.IsEmpty(tRecorderList)) {
            log.info("OnPlayRecord:callid={} nofind", callid);
            return;
        }
        TRecorder tRecorder = tRecorderList.get(0);
        String fwav = "";
        if (JPubUtils.IsEqual(tRecorder.getAgentid(), "qm") ||
                JPubUtils.IsEqual(tRecorder.getAgentid(), "ivr") ||
                JPubUtils.IsEqual(tRecorder.getAgentid(), "robotai")) {
            fwav = cti_robotRecfileDir + tRecorder.getFilepath() + tRecorder.getFilename();
        } else {
            fwav = cti_recfileDir + tRecorder.getFilepath() + tRecorder.getFilename();
        }
        log.info("OnPlayRecord:file={}", fwav);
        try {
            response.addHeader("Content-Type", "audio/mpeg;charset=utf-8");
            File file = new File(fwav);
            byte[] buf = new byte[2048];
            FileInputStream fis = new FileInputStream(file);
            ServletOutputStream out = response.getOutputStream();
            int len_l = 0;
            while ((len_l = fis.read(buf)) != -1) {
                out.write(buf, 0, len_l);
            }
            log.info("OnPlayRecord({}) End.", callid);
            out.flush();
            out.close();
            fis.close();
        } catch (Exception e) {
            log.error("OnPlayRecord.Err:", e);
        }
    }

    @Override
    public UpRecResVo UploadRecord(MultipartFile file) {
        String uploadPath = upload_filedir;
        try {
            log.info("UploadRecord:uploadPath={}", uploadPath);
            if (!uploadPath.endsWith("/")) uploadPath += "/";
            String fileName = file.getOriginalFilename();
            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String fileDatePath = LocalDate.now().format(dateFormatter);
            uploadPath += fileDatePath + "/";
            File parentPath = new File(uploadPath);
            if (!parentPath.exists()) {
                parentPath.mkdir();
            }
            String wavformat = fileName.substring(fileName.lastIndexOf("."));
            String reckeyid = "R" + JPubUtils.getSerialNumber();
            String newName = reckeyid + wavformat;
            log.info("UploadRecord:uploadPath={},newName={}", uploadPath, newName);
            File newFile = new File(parentPath, newName);
            file.transferTo(newFile);   //复制文件
            int recspan = getAudioDuration(newFile, wavformat);

            if (JPubUtils.IsEmpty(upload_ipaddr)) {
                upload_ipaddr = JPubUtils.getLocalIpAddr();
            }

            UpRecResVo resVo = new UpRecResVo();
            resVo.setIpaddr(upload_ipaddr);
            resVo.setFilename(newName);
            resVo.setFilepath(uploadPath);
            resVo.setFilekey(reckeyid);
            resVo.setRecspan(recspan);
            return resVo;
        } catch (Exception e) {
            log.warn("UploadRecord.Err:{}", e.getMessage());
            throw new ServiceException(EnumRCode.FileUploadErr.value,
                    EnumRCode.FileUploadErr.name + ":" + e.getMessage()
            );
        }
    }

    public static int getAudioDuration(File wavFile, String wavformat) {
        try {
            log.info("getAudioDuration={}", wavformat);
            if (JPubUtils.IsEqual(wavformat.toLowerCase(), ".mp3") ||
                    JPubUtils.IsEqual(wavformat.toLowerCase(), "mp3")) {
                MP3File f = (MP3File) AudioFileIO.read(wavFile);
                MP3AudioHeader audioHeader = (MP3AudioHeader) f.getAudioHeader();
                return audioHeader.getTrackLength();
            } else {
                AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(wavFile);
                AudioFormat format = audioInputStream.getFormat();
                long audioFileLength = wavFile.length();
                int frameSize = format.getFrameSize();
                float frameRate = format.getFrameRate();
                return (int) (audioFileLength / (frameSize * frameRate));
            }
        } catch (Exception e) {
            log.warn("getAudioDuration.Err:{}", e.getMessage());
            return 0;
        }
    }
}




